//
//  Conversion.cpp
//  NumberConverter
//
//  Created by Kyle Sherman on 8/14/10.
//  Copyright (c) 2010 __MyCompanyName__. All rights reserved.
//

#include "Conversion.h"
#include <iostream>
#include <sstream>
#include <string>
#include <math.h>
#include <stack>

using namespace std;

void Conversion::setInputString(string input)
{
    inputString = input;
}

string Conversion::getConvertedString()
{
    return convertedString;
}

//Decimal to *
void Conversion::dectobin(bool learnMode)
{	
	string solution;
	stack <int> answer;
	int number;
	int digit;
	
	while (number!=0) {
		digit = number%2; //sets digit equal to 0 or 1
		answer.push(digit); //puts the 0 or 1 onto stack so that it can be reversed at the end 
		number = number/2;
	}
	
	while (!(answer.empty())) {
        solution.push_back(answer.top()+48); //put number from top of stack onto back of solution string
        //add 48 to make it a character that is displayable
        answer.pop(); //pop the top number off of the stack
	}
	
    convertedString = solution;
    //solution is the final output
}

void Conversion::dectohex(bool learnMode)
{
    const char* decNumber;
    decNumber = inputString.c_str();
    
    conversionStream << decNumber;
    int length = conversionStream.str().length();
    
    int temp;
    conversionStream >> temp;
    char converted[length];
    sprintf(converted, "%X", temp);
    convertedString = (string)converted;
}

void Conversion::dectooct(bool learnMode)
{
    const char* decNumber;
    decNumber = inputString.c_str();
	
    conversionStream<< decNumber;
    int length = conversionStream.str().length();
    
    int temp;
    conversionStream >> temp;
    char converted[length];
    sprintf(converted, "%o", temp);
    convertedString = (string)converted;

}

//Binary to *
void Conversion::bintodec(bool learnMode)
{
    long long decimal = 0;
	int power = 0;
    
	for (int i = inputString.length()-1; i >= 0; i--) 
	{
		if (inputString.at(i) == '0') 
		{
        }
		else if (inputString.at(i) == '1')
		{
			decimal = decimal+pow(2, power);
		}
		else 
		{
			return; //break the for loop so that the output.text in the next statement is not shown
		}
		power++;

        char converted[sizeof(decimal)];
        sprintf(converted, "%llu", decimal);
        convertedString = (string)converted;
	}
}

void Conversion::bintohex(bool learnMode)
{
    long long decimal = 0;
	int power = 0;
	
	for (int i = inputString.length()-1; i >= 0; i--) 
	{
		if (inputString.at(i) == '0') 
		{
		}
		else if (inputString.at(i) == '1')
			decimal = decimal+pow(2, power);
		else 
            return;
		power++;
	}
	conversionStream << hex;
	conversionStream << decimal;
	
	string dude1 = conversionStream.str();
	
	for (int i = 0; i < dude1.length(); i++)
		dude1[i] = toupper(dude1[i]);
	
	convertedString = dude1.c_str();
}

void Conversion::bintooct(bool learnMode)
{
    long long decimal = 0;
	int power = 0;
	
	for (int i = inputString.length()-1; i >= 0; i--) 
	{
		if (inputString.at(i) == '0') 
		{
		}
		else if (inputString.at(i) == '1')
            decimal = decimal+pow(2, power);
		else 
			return;
		power++;
	}
	
	conversionStream << oct;
	conversionStream << decimal;
	
	string dude2 = conversionStream.str();
	
	for (int i = 0; i < dude2.length(); i++)
		dude2[i] = toupper(dude2[i]);
	
	convertedString = dude2.c_str();
}

//Hex to *
void Conversion::hextodec(bool learnMode)
{
    Conversion::hextobin(learnMode);
    Conversion::bintodec(learnMode);
}

void Conversion::hextobin(bool learnMode)
{
    string zero = "0000";
    string one = "0001";
    string two = "0010";
    string three = "0011";
    string four = "0100";
    string five = "0101";
    string six = "0110";
    string seven = "0111";
    string eight = "1000";
    string nine = "1001";
    string a = "1010";
    string b = "1011";
    string c = "1100";
    string d = "1101";
    string e = "1110";
    string f = "1111";
    
    for (int n=0; n < inputString.length(); n++)
    {
        switch (inputString.at(n))
        {
            case '0':
                conversionStream << zero;
                break;
            case '1':
                conversionStream << one;
                break;
            case '2':
                conversionStream << two;
                break;
            case '3':
                conversionStream << three;
                break;
            case '4':
                conversionStream << four;
                break;
            case '5':
                conversionStream << five;
                break;
            case '6':
                conversionStream << six;
                break;
            case '7':
                conversionStream << seven;
                break;
            case '8':
                conversionStream << eight;
                break;
            case '9':
                conversionStream << nine;
                break;
            case 'A':
                conversionStream << a;
                break;
            case 'a':
                conversionStream << a;
                break;
            case 'B':
                conversionStream << b;
                break;
            case 'b':
                conversionStream << b;
                break;
            case 'C':
                conversionStream << c;
                break;
            case 'c':
                conversionStream << c;
                break;
            case 'D':
                conversionStream << d;
                break;
            case 'd':
                conversionStream << d;
                break;
            case 'E':
                conversionStream << e;
                break;
            case 'e':
                conversionStream << e;
                break;
            case 'F':
                conversionStream << f;
                break;
            case 'f':
                conversionStream << f;
                break;
            default:
                return;
        }
    }
    convertedString = conversionStream.str().c_str();
}

void Conversion::hextooct(bool learnMode)
{	
	conversionStream << dec;
	conversionStream << inputString;
	
	convertedString = conversionStream.str();
}

//Oct to *
void Conversion::octtodec(bool learnMode)
{
	conversionStream << dec;
	conversionStream << inputString;
	
	convertedString = conversionStream.str();
}

void Conversion::octtobin(bool learnMode)
{
    string zero = "000";
    string one = "001";
    string two = "010";
    string three = "011";
    string four = "100";
    string five = "101";
    string six = "110";
    string seven = "111";
    
    for (int n=0; n < inputString.length(); n++)
    {
        switch (inputString.at(n))
        {
            case '0':
                conversionStream << zero;
                break;
            case '1':
                conversionStream << one;
                break;
            case '2':
                conversionStream << two;
                break;
            case '3':
                conversionStream << three;
                break;
            case '4':
                conversionStream << four;
                break;
            case '5':
                conversionStream << five;
                break;
            case '6':
                conversionStream << six;
                break;
            case '7':
                conversionStream << seven;
                break;
            default:
                return;
        }
    }
    convertedString = conversionStream.str().c_str();
    
    /*
    conversionStream << dec;
	conversionStream << inputString;
	
	string dude10 = conversionStream.str();
	
	long long decimal2;
	string decimalstring2;
	string finalstring2;
	
	for (int p = 0; p < inputString.length()-1; p++)
		decimalstring2.at(p) = inputString.at(p);
	
	for (int q = 0; q<sizeof(decimalstring2); q++)
		decimal2 = decimal2*10 + decimalstring2.at(q) - 48;
	
	for (int r = 0; r<sizeof(decimal2); r++)
	{
		finalstring2.push_back(decimal2%2);
		decimal2 = decimal2 / 2;
	}
    convertedString = finalstring2.c_str();
     */
}

void Conversion::octtohex(bool learnMode)
{
    conversionStream << hex;
	conversionStream << inputString;
	
	string dude8 = conversionStream.str();
	
	convertedString = dude8.c_str();
}